<cfcomponent>

	<cffunction name="getPost" access="public" returntype="query">
    	<cfargument name="blogid" type="numeric" required="true">
		<cfargument name="postid" type="string" required="false" default="0" hint="the id of the post, if not supplied, show latest">
        <cfargument name="includeDraft" type="boolean" required="false" default="false">
        
        <!--- check the postid and if not specified, get the highest value --->
        <cfif arguments.postid EQ 0>
        	<cfset arguments.postid = getLatestPostId(blogid, includeDraft)>
        </cfif>
        
        <!--- if the postid is numeric, assume a id, otherwise assume a slug --->
        <cfif IsNumeric(postid) AND postid GT 0>
        	<cfset myResult = getPostById(blogid, postid, includeDraft)>
        <cfelse>
        	<cfset myResult = getPostBySlug(blogid, postid, includeDraft)>
        </cfif>
        
		<cfreturn myResult>
	</cffunction>
    
    
    <!--- access the data in the database --->
    <cffunction name="getPostById" access="public" returntype="query">
    	<cfargument name="blogid" type="numeric" required="true">
    	<cfargument name="postid" type="numeric" required="true">
        <cfargument name="includeDraft" type="boolean" required="false" default="false">
        
        <cfquery name="post" datasource="blog">
        	SELECT	*
            FROM	t_posts
            WHERE	post_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#postid#">
              AND   post_blog_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#blogid#">
            <cfif arguments.includeDraft>  AND	post_valid != 0<cfelse>  AND   post_valid = 1</cfif>
        </cfquery>
        
        <cfreturn post>
    </cffunction>
    
    <!--- access the data in the database --->
    <cffunction name="getPostBySlug" access="public" returntype="query">
    	<cfargument name="blogid" type="numeric" required="true">
    	<cfargument name="postslug" type="string" required="true">
        <cfargument name="includeDraft" type="boolean" required="false" default="false">
        
        <cfquery name="post" datasource="blog">
        	SELECT	*
            FROM	t_posts
            WHERE	post_slug = <cfqueryparam cfsqltype="cf_sql_varchar" value="#postslug#">
              AND   post_blog_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#blogid#">
            <cfif arguments.includeDraft>  AND	post_valid != 0<cfelse>  AND   post_valid = 1</cfif>
        </cfquery>
        
        <cfreturn post>
    </cffunction>
    
    
    
    <!--- get the last X posts --->
    <cffunction name="getLatestPosts" access="public" returntype="query">
    	<cfargument name="blogid" type="numeric" required="true">
        <cfargument name="recentNum" type="numeric" required="false" default="5">
        <cfargument name="includeDraft" type="boolean" required="false" default="false">
        <cfargument name="getFullData" type="boolean" required="false" default="false">
        
        <cfquery name="posts" datasource="blog">
        	SELECT	post_title, post_id, post_valid, post_slug
            <cfif arguments.getFullData>		,post_content, post_date</cfif>
            FROM	t_posts
            WHERE	post_blog_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#blogid#">
            <cfif arguments.includeDraft>  AND	post_valid != 0<cfelse>  AND   post_valid = 1</cfif>
            ORDER BY post_id DESC
            LIMIT	#recentNum# 
        </cfquery>
        
        <cfreturn posts>
    </cffunction>
    
    <!--- get the latest valid post --->
    <cffunction name="getLatestPostId" access="private" returntype="numeric" description="get the latest post id">
    	<cfargument name="blogid" type="numeric" required="true">

    	<cfset var latestPostId = -1>

    	<cfquery name="maxId" datasource="blog">
        	SELECT	max(post_id) post_id
            FROM	t_posts
            WHERE	post_valid = 1
        </cfquery>
        
        <cfif maxId.post_id IS NOT ""><cfset latestPostId = maxId.post_id></cfif>
        
        <cfreturn latestPostId>
    </cffunction>
    
    <!--- save an new item to the database --->
    <cffunction name="saveItem" access="public" returntype="any" description="Adds a new blog post to the database">
    	<cfargument name="data" type="struct" required="true">
		<cfargument name="returnSlug" type="boolean" required="false" default="false">
        
        <cfset var postid = 0>
        <cfset var slug = "">
        <cfset var newPost = true>
        <cfset var postVersion = 1>
		<cfset var blogid = "">
        
        <cfif StructKeyExists(data, "post")>
	        <cfset postid = data.post>
            <cfset newPost = false>
        <cfelse>
        	<cfset postid = getNextItemId()>
        </cfif>
        
		<!--- validate that the item is supplied --->
        <cfif NOT StructKeyExists(data, "posttitle")
			OR NOT StructKeyExists(data, "blogid")
			OR NOT StructKeyExists(data, "postbody")>
			<cfthrow message="unable to save item, not all fields are defined">
        </cfif>

		<!--- check the value supplied for blog id --->
		<cfset blogid = data.blogid>
		<cfif NOT IsNumeric(data.blogid)>
			<!--- attempt to translate a non-numeric id to a numeric one --->
			<cfset objBlog = CreateObject("component", "obj_blog")>
			<cfset blogid = objBlog.getBlogIdByName(data.blogid)>
			<cfif NOT IsNumeric(blogid)>
				<cfthrow message="unable to convert the supplied blog name '#data.blogid#' to a number">
			</cfif>
		</cfif>
        
        <!--- create the slug --->
        <cfset slug = REReplace(lcase(data.posttitle), "[^a-z0-9]+", "_", "ALL")>
        
        <cftransaction isolation="repeatable_read">
        	<cfif NOT newPost>
	        	<cfquery name="version" datasource="blog">
                	SELECT	max(post_version)+1 as nextid
                    FROM	t_posts 
                    WHERE	post_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#postid#">
                      AND	post_blog_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#blogid#">
                </cfquery>
                <cfset postVersion = version.nextid>
            </cfif>
            
            <cfquery datasource="blog">
                INSERT INTO t_posts
                    (post_id,
                    post_title,
                    post_slug,
                    post_date,
                    post_comment_count,
                    post_date_modified,
                    post_content,
                    post_valid,
                    post_blog_id,
                    post_version,
                    post_editor_id)
                VALUES
                    (<cfqueryparam cfsqltype="cf_sql_integer" value="#postid#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar" value="#data.posttitle#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar" value="#slug#">,
                    <cfqueryparam cfsqltype="cf_sql_timestamp" value="#now()#">,
                    0,
                    <cfqueryparam cfsqltype="cf_sql_timestamp" value="#now()#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar" value="#data.postbody#">,
                    <cfif StructKeyExists(form, "save")>1<cfelse>2</cfif>,
                    <cfqueryparam cfsqltype="cf_sql_integer" value="#blogid#">,
                    <cfqueryparam cfsqltype="cf_sql_integer" value="#postVersion#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar" value="#cookie.acfbid#">)
            </cfquery>
            
			<!--- if this is an edit, then invalidate the old posts --->
            <cfif NOT newPost>
                <cfquery datasource="blog">
                    UPDATE	t_posts
                    SET		post_valid = 0
                    WHERE	post_blog_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#data.blogid#">
                      AND	post_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#postid#">
					  AND	post_version < <cfqueryparam cfsqltype="cf_sql_integer" value="#postVersion#">
                </cfquery>
            </cfif>
        </cftransaction>
		
		<!--- return either the id or the slug, depending on the insruction --->
		<cfif returnSlug><cfreturn slug><cfelse><cfreturn postid></cfif>
    </cffunction>

    <!--- save an new item to the database --->
    <cffunction name="getNextItemId" access="private" returntype="numeric" description="Fetches the next item id from the database">
    	<cfset var seq = queryNew("")>
        
        <cftransaction isolation="repeatable_read">
        	<cfquery datasource="blog">UPDATE sequences SET post_seq = post_seq + 1</cfquery>
	    	<cfquery name="seq" datasource="blog">
        		SELECT post_seq FROM sequences
            </cfquery>
        </cftransaction>
        
        <cfreturn seq.post_seq>
    </cffunction>

</cfcomponent>